home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / Mac Satellite.sit / Mac Satellite / MacSeason9 v1.7 / MacSeason9v1.7 / MacSeason9.src / decrypt9.c next >
Text File  |  1995-08-15  |  10KB  |  438 lines

  1. /*    Latest change: 15/08/95
  2.     Fixed access to addresses $0088 and $00EE. 
  3.   12/08/95
  4.     Corrected implementation of nanocommand 0F. Perhaps this will work.
  5.   03/08/95
  6.     Fixed 'new' nanocommand 0F. Thanks to Ian for the fix.
  7.   10/07/95
  8.     Introduced the kernel counter as an attempt to get MacSeason running on
  9.     slow, slow Macs (read 68000/8Mhz)
  10.   07/07/95
  11.     I'm now using D0 instead of a global variable to pass the keybyte to 
  12.     SkyKernel.
  13.   29/06/95
  14.     Reinstated nanocommand 28. Fixed a (stupid) bug. Maybe one day I'll learn
  15.     to count...
  16.   25/06/95
  17.     Some further optimizations for slower Macs.
  18.   15/06/95
  19.     Sky ECM: Nanocmd access to address $e7 fixed.
  20.   12/06/95
  21.     Some minor changes to further improve the speed of this routines.
  22.   29/05/95
  23.     I changed a lot of details to optimize performance when compiled with
  24.     Symantec C 7.0 on an 680x0 based Macintosh. One of the major changes was
  25.     the redefinition of SkyKernel with no parameters. This saves some stack
  26.     operations that would be necessary otherwise and thus saves processing
  27.     time.
  28.     Loops are now always do-while-loops, since Think C produces one branch 
  29.     command more for while() or for-loops.
  30.     Also, I tried to avoid accessing the 32-byte message or the 8-byte answer
  31.     as an array. Access to an array like
  32.         theByte = msg[i];
  33.     usually gets translated into something like
  34.         move $00(Ax,Dx), Dx
  35.     which requires 14 clock periods on an 68000. Written as
  36.         theByte = *msg++;
  37.     it gets translated into
  38.         move (Ax)+, Dx
  39.     which requires only 8 clock periods on an 68000 and is perfectly well
  40.     suited for this purpose.
  41.     Another optimization was the use of the inline assembler to program
  42.     bit shifting with the rol.b or ror.b command. E.g. if you want to rotate
  43.     the byte aByte one bit to the left, in C you write something like this:
  44.         aByte = (aByte << 1) | (aByte >> 7);
  45.     Alas, Think C translates this into: (Dx being one of the data registers)
  46.         MOVE.B    aByte,Dx
  47.         ASR.W     #$7,Dx
  48.         ADD.B     aByte,aByte ; same as 'ASL.W #$1, aByte' only faster
  49.         OR.B      Dx,aByte
  50.     which does exactly the same as the rol.b #1,aByte command, only slower. 
  51.     (32 clock cycles instead of 8 for the rol.b command.) Therefore the
  52.     rol.b command is used 'manually'. This requires aByte to be of type register.
  53.     Suggestions for further optimization welcome.
  54. */
  55.         
  56.  
  57. #include "decrypt9.h"
  58. #include "MacSeason9.h"
  59.  
  60. unsigned char    theBigTable[16384];
  61. unsigned char    bTable[256];
  62.  
  63. short    checksum;
  64. short    kernelCount;
  65. extern short    reallyDecode;
  66.  
  67. unsigned char theNanos[16];
  68.  
  69. unsigned char *cardReply; /* Global pointer to cardreply to save on some stack operations */
  70. short    oi;
  71.  
  72. extern vcPrefs prgPrefs;
  73.  
  74. unsigned char kPleaseWait[1] = {
  75.     0x60
  76. };
  77.  
  78. unsigned char theKeyByte;
  79.  
  80. #define TABLESIZE    8192
  81. #define HALFTABLE    4096
  82. #define tBigTable    132
  83.  
  84. unsigned char nanoLengths[256];
  85.  
  86. void InitNanoLens( void )
  87. {
  88.     short i;
  89.     
  90.     i = 255;
  91.     do {
  92.         nanoLengths[i] = 0x10;
  93.     } while (--i >= 0);
  94.     nanoLengths[0x09] = 3;
  95.     nanoLengths[0x0C] = 2;
  96.     nanoLengths[0x11] = 4;
  97.     nanoLengths[0x14] = 5;
  98.     nanoLengths[0x19] = 1;
  99.     nanoLengths[0x1D] = 2;
  100.     nanoLengths[0x24] = 3;
  101.     nanoLengths[0x28] = 5;
  102.     nanoLengths[0x2c] = 1;
  103.     nanoLengths[0x30] = 2;
  104.     nanoLengths[0x34] = 4;
  105.     nanoLengths[0x39] = 2;
  106.     nanoLengths[0x3c] = 1;
  107.     nanoLengths[0x41] = 1;
  108.     nanoLengths[0x46] = 1;
  109.     nanoLengths[0x49] = 1;
  110. }
  111.  
  112.  
  113. void SkyKernel( void )
  114. {
  115.     register unsigned short j,k;
  116.  
  117.     asm {
  118.         movea.l    cardReply, a1
  119.         moveq    #2, d1
  120.         moveq    #0, j
  121.         moveq     #0, k
  122.         move.b    (a1)+, k;
  123.         lea        bTable, a0
  124.     @kernelLoop:
  125.         move.b    k,j
  126.         move.b    0(a0,j), k
  127.         add.b    d0, k
  128.         sub.b    (a1), k
  129.         sub.b    (a1)+, j
  130.         eor.b    d0, j
  131.         mulu.w    k, j
  132.         eor.b    j, (a1)
  133.         move.b    (a1)+, k
  134.         lsr.w    #8, j
  135.         add.b    j, (a1)
  136.         rol.b    #1,d0
  137.         addi.b    #0x49, d0
  138.         dbra    d1, @kernelLoop
  139.         move.b    j, theBigTable[0x1FFF - 0xE7]
  140.         move.b    (a1), j
  141.         mulu.w    k, j
  142.         subq    #7, a1
  143.         moveq    #0x39, k
  144.         move.b    (a1), d0
  145.         add.b    j, d0
  146.         addx.b    k, d0
  147.         move.b    d0, (a1)+
  148.         moveq    #-113, k            // -113 = 0x8f
  149.         lsr.w    #8, j
  150.         move.b    (a1), d0
  151.         add.b    j, d0
  152.         addx.b    k, d0
  153.         move.b    d0, (a1)
  154.         move.b     #6, theBigTable[0x1FFF - 0x88]
  155.     }
  156.     if (--kernelCount == 0) {
  157.         send( kPleaseWait, 1);
  158.         kernelCount = prgPrefs.kernelCount;
  159.     }
  160. }
  161.  
  162. short decode( unsigned char *theMsg, unsigned char *answ)
  163. {
  164.     register long i;
  165.     register unsigned char aChar;
  166.     register unsigned char theByte;
  167.     register unsigned char *nanoPtr;
  168.     register unsigned char *nanoEnd;
  169.     register unsigned char *msg;
  170.     register unsigned char c;
  171.     register unsigned char d;
  172.     register short    NanoActive;
  173.     short    offset;
  174.  
  175.     kernelCount = prgPrefs.kernelCount;
  176.     aChar    = 0x00;
  177.     theByte    = 0x00;
  178.     msg        = theMsg;
  179.     msg++;
  180.     
  181.     cardReply = nanoPtr = answ;
  182.     asm {
  183.         // Clear 8 byte answer
  184.         clr.l (nanoPtr)+
  185.         clr.l (nanoPtr)
  186.     }
  187.     
  188. /* Calculate Nanocommands */
  189.     /* msg is already pointing to theMsg[1] */
  190.  
  191.     asm {
  192.         move.b    (msg)+, theByte
  193.         move.b    (msg)+, aChar
  194.         eor.b    aChar, theByte
  195.         rol.b    #4, theByte;
  196.         rol.b    #1, aChar
  197.         add.b    theByte, aChar
  198.     }
  199.     if ((NanoActive = ((aChar ^ *msg++) - 0x80)) == 0) {
  200.         asm {
  201.             rol.b    #1, aChar
  202.             add.b    theByte, aChar
  203.             rol.b    #1, aChar
  204.             add.b    aChar, theByte
  205.             moveq    #14, i
  206.             lea     theNanos, nanoPtr
  207.             addq    #8, msg
  208.         @calcnano:
  209.             move.b    (msg)+, d0
  210.             eor.b    theByte, d0
  211.             move.b    d0, (nanoPtr)+
  212.             dbra    i,@calcnano
  213.         }
  214.     }
  215.     checksum = 0;
  216.     
  217.     if (reallyDecode) {
  218.         msg = theMsg;
  219.     
  220.         /* Do decoding */
  221.         asm {
  222.                 moveq    #26, i
  223.         @loop27    move.b    (msg)+, d0        //theKeyByte
  224.                 jsr        SkyKernel
  225.                 dbra    i,@loop27
  226.         }
  227.     
  228.         theByte     = 0x00;
  229.     
  230.         i = 4;                /* Check signature in bytes 27 - 30 */
  231.         nanoPtr = &answ[7];    /* This makes the loop a bit faster */
  232.         do {
  233.             asm {
  234.                 move.b    theByte, d0        //theKeyByte
  235.                 jsr        SkyKernel
  236.                 move.b    theByte, d0        //theKeyByte
  237.                 jsr        SkyKernel
  238.                 move.b    (msg)+, theByte
  239.             }
  240.             if ( theByte != *nanoPtr) checksum |= 1;
  241.         } while (--i);
  242.     
  243.         theByte = *msg;
  244.     }
  245.     if (checksum == 0) {
  246.         if ((NanoActive==0)) {
  247.             if (prgPrefs.debug) DrawNanos( theNanos);
  248.             nanoPtr = &theNanos[0];
  249.             nanoEnd = &theNanos[16];
  250.             do {
  251.                 asm {
  252.                     move.b (nanoPtr), d0
  253.                 }
  254.                 case09:
  255.                     asm {
  256.                         cmpi.b     #0x09, d0
  257.                         bne        @case0f
  258.                     }
  259.                     ((unsigned char *)&offset)[0] = nanoPtr[1];
  260.                     ((unsigned char *)&offset)[1] = nanoPtr[2];
  261.                     theByte    = 0x63;
  262.                     aChar    = 0;
  263.                     goto switchEnd;
  264.                 case0f:
  265.                     asm {
  266.                         cmpi.b  #0x0f, d0
  267.                         bne        @case11
  268.                     }
  269.                     theByte    = nanoPtr[1];
  270.                     nanoPtr = nanoEnd;
  271.                     ((unsigned char *)&offset)[0] = theBigTable[0x1fff - 0x00bf] & 0x1f;
  272.                     ((unsigned char *)&offset)[1] = theBigTable[0x1fff - 0x00c0];
  273.                     goto case112;
  274.                 case11:
  275.                     asm {
  276.                         cmpi.b     #0x11, d0
  277.                         bne        @case19
  278.                     }
  279.                     theByte    = nanoPtr[1];
  280.                     ((unsigned char *)&offset)[0] = 0x1f & nanoPtr[2];
  281.                     ((unsigned char *)&offset)[1] = nanoPtr[3];
  282.                 case112:    
  283.                     aChar = theByte;
  284.                     if (offset == 0x0081) {
  285.                         aChar &= 0xb7;
  286.                         aChar += 0x40;
  287.                     } else if (offset == 0x00EE) {
  288.                         nanoPtr = &theNanos[aChar];
  289.                     }
  290.                     theBigTable[0x1fff-offset] = aChar;
  291.                     aChar    = 0;
  292.                     goto switchEnd;
  293.                 case19:
  294.                     asm {
  295.                         cmpi.b     #0x19, d0
  296.                         bne        @case28
  297.                     }
  298.                     theByte    = nanoPtr - theNanos;                
  299.                     aChar    = 0x19;
  300.                     goto switchEnd;
  301.                 case28:
  302.                     asm {
  303.                         cmpi.b     #0x28, d0
  304.                         bne        @case30
  305.                     }
  306.                     /* this really copies the 4 following bytes to $8D-$90 */
  307.                     aChar    = nanoPtr - theNanos;
  308.                     theByte = nanoPtr[4];
  309.                     goto switchEnd;                        
  310.                 case30:
  311.                     asm {
  312.                         cmpi.b     #0x30, d0
  313.                         bne        @case39
  314.                     }
  315.                     i = nanoPtr[1];
  316.                     msg = &theBigTable[0x1fff];
  317.                     if  ((char)msg[ -0x08] < 0)  {    // ECM 05/17/95
  318.                         msg += 0x2000;
  319.                     }
  320.                     msg -= offset;
  321.                     msg -= i;
  322.                     asm {
  323.                         @301:    move.b    (msg)+, d0    //theKeyByte
  324.                                 jsr        SkyKernel
  325.                                 dbra i,@301
  326.                                 move.b    -(msg), theByte
  327.                     }
  328.                     aChar = 0xff;
  329.                     goto switchEnd;
  330.                 case39:
  331.                     asm {
  332.                         cmpi.b     #0x39, d0
  333.                         bne        @case46
  334.                     }
  335.                     theByte = ((unsigned char *)&offset)[1];
  336.                     aChar    = ((unsigned char *)&offset)[0];
  337.                     break;
  338.                 case46:
  339.                     asm {
  340.                         cmpi.b     #0x46, d0
  341.                         bne        @dflt
  342.                     }
  343.                     goto exitdecode;
  344.                 dflt: // also 0x03
  345.                     asm {
  346.                         cmpi.b    #0x03, d0
  347.                         beq        @nanoLoopEnd
  348.                     }
  349.                     SysBeep(0);
  350.                     goto nanoLoopEnd;
  351.                 switchEnd:
  352.                 asm {
  353.                     move.b    theByte, d0
  354.                     jsr        SkyKernel
  355.                     move.b    aChar, d0
  356.                     jsr        SkyKernel
  357.                 }
  358.                 nanoPtr += nanoLengths[*nanoPtr];
  359.             } while ((nanoPtr < nanoEnd));
  360. nanoLoopEnd:
  361.             theByte = nanoPtr - theNanos;
  362.         } // if nanoActive
  363.         if (reallyDecode) {
  364.             asm {
  365.                 moveq    #63, i
  366.             @3    move.b    theByte, d0    //theKeyByte
  367.                 jsr        SkyKernel
  368.                 dbra    i,@3
  369.             }
  370.             msg   = theMsg;
  371.             asm {
  372.                     moveq    #0,aChar
  373.                     moveq    #31, i
  374.             @cs1    add.b     (msg)+,aChar
  375.                     dbra     i,@cs1
  376.             }
  377.             if (aChar) checksum |= 2;
  378.         }
  379.     }
  380.     if ( checksum ) {
  381.         nanoPtr = answ; /* use a register */
  382.         asm {
  383.             clr.l    (nanoPtr)+
  384.             clr.l    (nanoPtr)
  385.             subq.l    #4,nanoPtr
  386.             move.b    #1,(nanoPtr)
  387.         }
  388.     }
  389. exitdecode:
  390.     return(checksum);
  391. }
  392.  
  393. void InitDecode( void )
  394. {
  395.     Handle theRes;
  396.     short j,k;
  397.     unsigned char d, e;
  398.     unsigned char *theTable;
  399.  
  400.     theRes = GetResource(tableResource,tBigTable);
  401.     HLock(theRes);
  402.     theTable = (unsigned char *)*theRes;
  403.     j = 0;
  404.     d = *theTable++;
  405.     do {
  406.         e = *theTable++;
  407.         if (e == d) {
  408.             k = *theTable++;
  409.             e = *theTable++;
  410.             do {
  411.                 theBigTable[j] = e;
  412.                 j++;
  413.             }
  414.             while (--k);
  415.         } else {
  416.             theBigTable[j] = e;
  417.             j++;
  418.         }
  419.     }
  420.     while (j < TABLESIZE);
  421.     theTable = theBigTable;
  422.     for (j = 0; j < HALFTABLE; j++) {
  423.         *theTable ^= theTable[1];
  424.         theBigTable[TABLESIZE+j] = theBigTable[HALFTABLE+j] + *theTable++;
  425.         theBigTable[HALFTABLE+j] = 0;
  426.     }
  427.     HUnlock(theRes);
  428.     ReleaseResource(theRes);
  429.     theRes = GetResource(tableResource,kSkyKeyTable);
  430.     HLock(theRes);
  431.     BlockMove(*theRes, bTable    , 64);
  432.     BlockMove(*theRes, bTable+ 64, 64);
  433.     BlockMove( bTable, bTable+128, 128);
  434.     HUnlock(theRes);
  435.     ReleaseResource(theRes);
  436.     InitNanoLens();
  437. }
  438.